<template>
	<el-dialog v-model="model" :title="t('accountManagement.passwordModal.title')" width="480px" destroy-on-close>
		<el-carousel ref="carousel" :autoplay="false" arrow="never" indicator-position="none" :initial-index="0"
			height="240px">
			<el-carousel-item name="verifyEmail">
				<el-form ref="verifyForm" :model="verifyFormData" :rules="verifyRules">

					<el-form-item prop="email">
						<el-input v-model.trim="verifyFormData.email" :placeholder="t('login.emailPlaceholder')" />
					</el-form-item>
					<el-form-item prop="code">
						<div style="display: flex; width: 100%">
							<el-input style="flex: 1" v-model.trim="verifyFormData.code" :placeholder="t('login.codePlaceholder')" />
							<el-button :disabled="!verifyFormData.email || timerCount > 0" :loading="sending" style="padding: 0 12px"
								type="text" @click="sendEmailCode(verifyFormData.email)">{{ codeSendLabel }}</el-button>
						</div>
					</el-form-item>
					<el-form-item prop="oldPassword">
						<el-input v-model.trim="verifyFormData.oldPassword" type="password" show-password
							:placeholder="t('accountManagement.passwordModal.oldPasswordPlaceholder')" />
					</el-form-item>
					<el-form-item>
						<el-button style="margin-left: auto" @click="handleCancel">
							{{ t('accountManagement.passwordModal.cancel') }}
						</el-button>
						<el-button :loading="submitting"
							:disabled="!verifyFormData.email || !verifyFormData.code || !verifyFormData.oldPassword" type="primary"
							@click="handleNextStep">{{ t('accountManagement.passwordModal.next') }}</el-button>
					</el-form-item>
				</el-form>
			</el-carousel-item>

			<el-carousel-item name="setPassword">
				<el-form ref="passwordForm" :model="passwordFormData" :rules="passwordRules">
					<el-form-item prop="password">
						<el-input v-model.trim="passwordFormData.password" type="password" show-password
							:placeholder="t('login.passwordPlaceholder')" />
					</el-form-item>
					<el-form-item prop="againPassword">
						<el-input v-model.trim="passwordFormData.againPassword" type="password" show-password
							:placeholder="t('login.passwordAgainPlaceholder')" />
					</el-form-item>
					<el-form-item>
						<el-button style="margin-left: auto" @click="carousel.prev()">
							{{ t('accountManagement.passwordModal.prev') }}
						</el-button>
						<el-button :loading="submitting" :disabled="!passwordFormData.password || !passwordFormData.againPassword"
							type="primary" @click="handleSave">{{ t('accountManagement.passwordModal.save') }}</el-button>
					</el-form-item>
				</el-form>
			</el-carousel-item>
			<el-carousel-item name="result">
				<p>{{ t('accountManagement.passwordModal.successTitle') }}</p>
				<el-button style="margin: 0 auto" type="primary" @click="handleCloseResult">
					{{ t('accountManagement.passwordModal.close') }}
				</el-button>
			</el-carousel-item>
		</el-carousel>
	</el-dialog>
</template>
<script setup>
import { nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { CheckEmailCode, GetCodeOfEmail, restPassword } from '~/apis/web';
import { userStore } from '~/composables/store/modules/user';

const { t } = useI18n();
const model = defineModel({ type: Boolean });
const store = userStore();
const carousel = ref(null);
const verifyForm = ref(null);
const passwordForm = ref(null);
const verifyFormData = reactive({
	oldPassword: '',
	email: '',
	code: '',
});

const passwordFormData = reactive({
	password: '',
	againPassword: '',
});

const verifyRules = computed(() => ({
	oldPassword: [{ required: true, message: t('accountManagement.passwordModal.oldPasswordRequired') }],
	email: [
		{ required: true, message: t('accountManagement.passwordModal.emailRequired') },
		{ type: 'email', message: t('accountManagement.passwordModal.emailInvalid'), trigger: 'blur' },
	],
	code: [{ required: true, message: t('accountManagement.passwordModal.codeRequired') }],
}));

const passwordRules = computed(() => ({
	password: [{ required: true, message: t('accountManagement.passwordModal.passwordRequired') }],
	againPassword: [
		{ required: true, message: t('accountManagement.passwordModal.confirmPasswordRequired') },
		{
			validator: (_, value, callback) => {
				if (value !== passwordFormData.password) {
					callback(new Error(t('accountManagement.passwordModal.passwordMismatch')));
				} else {
					callback();
				}
			},
			trigger: 'blur',
		},
	],
}));

const submitting = ref(false);
const sending = ref(false);
const timer = ref(null);
const timerCount = ref(null);

const codeSendLabel = computed(() =>
	timerCount.value == null
		? t('accountManagement.passwordModal.sendCode')
		: timerCount.value > 0
			? t('accountManagement.passwordModal.countdown', { time: timerCount.value })
			: t('accountManagement.passwordModal.resend')
);

function resetState() {
	verifyFormData.oldPassword = '';
	verifyFormData.email = store.profile?.email || '';
	verifyFormData.code = '';
	passwordFormData.password = '';
	passwordFormData.againPassword = '';
	timerCount.value = null;
	stopTimer();
	verifyForm.value?.clearValidate();
	passwordForm.value?.clearValidate();
	nextTick(() => {
		carousel.value?.setActiveItem?.('verifyEmail');
	});
}

function handleCancel() {
	model.value = false;
}

function handleCloseResult() {
	model.value = false;
}

async function sendEmailCode(email) {
	if (!email || sending.value) return;
	try {
		sending.value = true;
		const body = {
			scene: 23,
			email,
		};
		const { code, data } = await GetCodeOfEmail(body);
		if (code === 0 && data) {
			startTimer();
		}
	} finally {
		sending.value = false;
	}
}

function startTimer() {
	stopTimer();
	timerCount.value = 60;
	timer.value = setInterval(() => {
		if (timerCount.value == null) return;
		timerCount.value -= 1;
		if (timerCount.value <= 0) {
			timerCount.value = 0;
			stopTimer();
		}
	}, 1000);
}

function stopTimer() {
	if (!timer.value) return;
	clearInterval(timer.value);
	timer.value = null;
}

async function handleNextStep() {
	if (!carousel.value || !verifyForm.value) return;
	const valid = await verifyForm.value.validate().then(() => true).catch(() => false);
	if (!valid) return;
	submitting.value = true;
	try {
		const body = {
			scene: 23,
			email: verifyFormData.email,
			code: verifyFormData.code,
		};
		const { code, data } = await CheckEmailCode(body);
		if (code === 0 && data) {
			carousel.value.next();
		}
	} finally {
		submitting.value = false;
	}
}

async function handleSave() {
	if (!carousel.value || !passwordForm.value) return;
	const valid = await passwordForm.value.validate().then(() => true).catch(() => false);
	if (!valid) return;
	submitting.value = true;
	try {
		const body = {
			email: verifyFormData.email,
			code: verifyFormData.code,
			oldPassword: verifyFormData.oldPassword,
			password: passwordFormData.password,
		};
		const { code, data } = await restPassword(body);
		if (code === 0 && data) {
			carousel.value.next();
		}
	} finally {
		submitting.value = false;
	}
}

watch(
	() => model.value,
	now => {
		if (now) {
			resetState();
		} else {
			stopTimer();
		}
	}
);
</script>
